<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
Code distributed by Google as part of the polymer project is also
subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
-->

<!--
`core-splitter` provides a split bar and dragging on the split bar
will resize the sibling element.  Use its `direction` property to indicate
which sibling element to be resized and the orientation.  Usually you would want
to use `core-splitter` along with flex layout so that the other sibling
element can be _flexible_.

Example:

    <div horizontal layout>
      <div>left</div>
      <core-splitter direction="left"></core-splitter>
      <div flex>right</div>
    </div>

In the above example, dragging the splitter will resize the _left_ element.  And
since the parent container is a flexbox and the _right_ element has
`flex`, the _right_ element will be auto-resized.

For horizontal splitter set `direction` to "up" or "down".

Example:

    <div vertical layout>
      <div>top</div>
      <core-splitter direction="up"></core-splitter>
      <div flex>bottom</div>
    </div>

@group Polymer Core Elements
@element core-splitter
@homepage github.io
-->

<link rel="import" href="../polymer/polymer.html">

<polymer-element name="core-splitter" attributes="direction locked minSize allowOverflow"
    on-trackstart="{{trackStart}}" on-track="{{track}}" on-down="{{preventSelection}}">

<template>

  <link rel="stylesheet" href="core-splitter.css">

</template>
<script>

  Polymer('core-splitter', {

    /**
     * Possible values are "left", "right", "up" and "down".
     *
     * @attribute direction
     * @type string
     * @default 'left'
     */
    direction: 'left',

    /**
     * Minimum width to which the splitter target can be sized
     *
     * @attribute minSize
     * @type number
     * @default 0
     */
    minSize: 0,

    /**
     * Locks the split bar so it can't be dragged.
     *
     * @attribute locked
     * @type boolean
     * @default false
     */
    locked: false,

    /**
     * By default the parent and siblings of the splitter are set to overflow hidden. This helps
     * avoid elements bleeding outside the splitter regions. Set this property to true to allow
     * these elements to overflow.
     *
     * @attribute allowOverflow
     * @type boolean
     * @default false
     */
    allowOverflow: false,

    ready: function() {
      this.directionChanged();
    },

    domReady: function() {
      if (!this.allowOverflow) {
        this.parentNode.style.overflow = this.nextElementSibling.style.overflow =
            this.previousElementSibling.style.overflow = 'hidden';
      }
    },

    directionChanged: function() {
      this.isNext = this.direction === 'right' || this.direction === 'down';
      this.horizontal = this.direction === 'up' || this.direction === 'down';
      this.update();
    },

    update: function() {
      this.target = this.isNext ? this.nextElementSibling : this.previousElementSibling;
      this.dimension = this.horizontal ? 'height' : 'width';
      this.classList.toggle('horizontal', this.horizontal);
    },

    targetChanged: function(old) {
      if (old) {
        old.style[old.__splitterMinSize] = '';
      }
      var min = this.target.__splitterMinSize = this.horizontal ? 'minHeight' : 'minWidth';
      this.target.style[min] = this.minSize + 'px';
    },

    trackStart: function() {
      this.update();
      this.size = parseInt(getComputedStyle(this.target)[this.dimension]);
    },

    track: function(e) {
      if (this.locked) {
        return;
      }
      var d = e[this.horizontal ? 'dy' : 'dx'];
      this.target.style[this.dimension] =
          this.size + (this.isNext ? -d : d) + 'px';
    },

    preventSelection: function(e) {
      e.preventDefault();
    }
  });

</script>
</polymer-element>